package com.my.study.chatting.service;

import com.my.study.chatting.MessageDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.server.ServerEndpointConfig;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

@Component
@ServerEndpoint("/websocket")
@Slf4j
public class WebSocketService extends ServerEndpointConfig.Configurator {

    // 可配置到配置文件
    private static final String ORIGIN = "my.test.com";

    //存放websocket的集合
    private static Map<String, Session> webSocketMap = new ConcurrentHashMap<>();

    //链接时
    @OnOpen
    public void onOpen(Session session) {
        webSocketMap.put(UUID.randomUUID().toString(), session);
        log.info("【websocket消息】有新的连接, 总数:{}", webSocketMap.size());
        session.getAsyncRemote().sendText("success");
    }

    //前端关闭时
    @OnClose
    public void onClose(Session session) {
        removeSession(session);
        log.info("【websocket消息】连接断开, 总数:{}", webSocketMap.size());
    }

    //前端向后端发送消息
    @OnMessage
    public void onMessage(Session session, String message) {
        session.getAsyncRemote().sendText("success");
        log.info("【websocket消息】收到客户端发来的消息:{}", message);
    }

    //前端向后端发送消息
    @OnError
    public void onError(Session session, String message) {
        removeSession(session);
        log.info("【websocket消息】异常:{}", message);
    }

    /**
     * 链接的域名校验
     *
     * @param originHeaderValue
     * @return
     */
    @Override
    public boolean checkOrigin(String originHeaderValue) {
        return Objects.equals(ORIGIN,originHeaderValue);
    }

    /**
     * 移除session
     *
     * @param session
     */
    private void removeSession(Session session) {
        for (Map.Entry<String, Session> entry : webSocketMap.entrySet()) {
            boolean flag = webSocketMap.remove(entry.getKey(), session);
            if (flag) {
                return;
            }
        }
    }

    /**
     * 发送到所有在线用户
     *
     * @param message
     */
    public void sendMessage(MessageDTO message) {
        try {
            webSocketMap.get(message.getToUserId()).getBasicRemote().sendText(message.getMessage());
        } catch (IOException e) {
            log.error("{}用户已下线", message.getToUserId(), e);
        }
    }

    /**
     * 发送到所有在线用户
     *
     * @param message
     */
    public void sendAllMessage(String message) {
        for (Map.Entry<String, Session> entry : webSocketMap.entrySet()) {
            log.info("【websocket消息】广播消息, message={}", message);
            try {
                entry.getValue().getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
